package at.ac.univie.zsu.aguataplan.service;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import at.ac.univie.zsu.aguataplan.dao.ClubDao;
import at.ac.univie.zsu.aguataplan.dao.Dao;
import at.ac.univie.zsu.aguataplan.dao.GameDao;
import at.ac.univie.zsu.aguataplan.dao.TeamDao;
import at.ac.univie.zsu.aguataplan.domain.Game;
import at.ac.univie.zsu.aguataplan.domain.Team;
import at.ac.univie.zsu.aguataplan.domain.Video;
import at.ac.univie.zsu.aguataplan.exception.DatabaseException;
import at.ac.univie.zsu.aguataplan.exception.LogicException;

/**
 * @author gerry
 * 
 */
@Service
public class GameManagerBean implements GameManager {
	private static Logger log = Logger.getLogger(GameManagerBean.class);

	@Autowired
	private GameDao gameDao;

	@Autowired
	private TeamDao teamDao;

	@Autowired
	private ClubDao clubDao;

	@Autowired
	private Dao dao;

	// ----------------------------------------------------
	// CONSTRUCTOR
	// ----------------------------------------------------

	public GameManagerBean() {

	}

	// ----------------------------------------------------
	// METHODS
	// ----------------------------------------------------

	@Override
	public void cleanGame() throws DatabaseException {
		try {
			gameDao.cleanGame();
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not delete entries", e.getMessage());
		}
	}

	// --------------

	@Override
	public Game addGame(String description, Team team1, Team team2, Date calDate, String gameResult)
			throws DatabaseException, LogicException {
		Game game = new Game();
		game.setDescription(description);
		game.setCalDate(calDate);
		game.setGameResult(gameResult);

		Team t1 = null;
		Team t2 = null;

		try {
			t1 = teamDao.getTeam(team1.getId());
			t2 = teamDao.getTeam(team2.getId());
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not load entry", e.getMessage());
		}

		game.addTeams(t1, t2);

		if (t1.getId() == t2.getId()) {
			throw new LogicException("a team can not play with themself", "");
		}

		Game retGame = null;

		try {
			retGame = gameDao.addGame(game);
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not save entry", e.getMessage());
		}

		return retGame;
	}

	@Override
	public void deleteGame(long id) throws DatabaseException {

		Game game;

		try {
			game = gameDao.getGame(id);
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not load entry", e.getMessage());
		}

		game.deleteTeams();

		try {
			gameDao.deleteGame(game.getId());
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not delete entry", e.getMessage());
		}

	}

	@Override
	public List<Game> getGameList() throws DatabaseException {
		List<Game> list = null;

		try {
			list = gameDao.getGameList();
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not get entries", e.getMessage());
		}
		return list;
	}

	@Override
	public Game mergeGame(Game game) throws DatabaseException {
		Game retGame = null;
		try {
			retGame = gameDao.mergeGame(game);
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not save entry", e.getMessage());
		}
		return retGame;
	}

	// --------------

	@Override
	public Video addVideo(Game game, String name, String description, String locationPath, double length,
			String videoCodec, String audioCodec) throws DatabaseException {
		Game g = null;

		try {
			g = gameDao.getGame(game.getId());
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not get entries", e.getMessage());
		}

		Video video = new Video();
		video.setName(name);
		video.setDescription(description);
		video.setLocationPath(locationPath);
		video.setLength(length);
		video.setVideoCodec(videoCodec);
		video.setAudioCodec(audioCodec);
		video.setRefTournament(g);

		g.addVideo(video);

		Video retVideo = null;

		try {
			retVideo = gameDao.addVideo(video);
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not save entry", e.getMessage());
		}

		try {
			gameDao.mergeGame(g);
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not save entry", e.getMessage());
		}

		return retVideo;
	}

	@Override
	public void deleteVideo(long gameId, long videoId) throws DatabaseException {
		Game g = null;

		try {
			g = gameDao.getGame(gameId);
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not get entries", e.getMessage());
		}

		g.deleteVideo(videoId);

		try {
			gameDao.mergeGame(g);
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not delete entry", e.getMessage());
		}

		try {
			gameDao.deleteVideo(videoId);
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not delete entry", e.getMessage());
		}

	}

	@Override
	public List<Video> getGameVideoList(Game game) throws DatabaseException {
		List<Video> list = null;

		try {
			list = gameDao.getGameVideoList(game);
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not get entries", e.getMessage());
		}

		return list;
	}

	@Override
	public Video mergeVideo(Video video) throws DatabaseException {
		Video retVideo = null;
		try {
			retVideo = gameDao.mergeVideo(video);
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new DatabaseException("could not save entry", e.getMessage());
		}
		return retVideo;
	}

	// ----------------------------------------------------
	// GETTER & SETTER
	// ----------------------------------------------------

	public ClubDao getClubDao() {
		return clubDao;
	}

	public GameDao getGameDao() {
		return gameDao;
	}

	public void setGameDao(GameDao gameDao) {
		this.gameDao = gameDao;
	}

	public void setClubDao(ClubDao clubDao) {
		this.clubDao = clubDao;
	}

	public Dao getDao() {
		return dao;
	}

	public void setDao(Dao dao) {
		this.dao = dao;
	}

	public TeamDao getTeamDao() {
		return teamDao;
	}

	public void setTeamDao(TeamDao teamDao) {
		this.teamDao = teamDao;
	}

}
